import { Food } from './Foods'
import { ScorePanel } from './ScorePanel'
import { Snake } from './Snake'
enum Direction {
  Up = 'ArrowUp',
  Down = 'ArrowDown',
  Left = 'ArrowLeft',
  Right = 'ArrowRight',
}
let timer: NodeJS.Timer | null
export class GameController {
  private snake: Snake
  private food: Food
  private scorePanel: ScorePanel
  isGameOver = true
  constructor() {
    this.snake = new Snake(150, 150)
    this.food = new Food()
    this.scorePanel = new ScorePanel()
  }
  private static instance: GameController = new GameController()
  public static getInstance() {
    return GameController.instance
  }

  init() {
    this.controlSnakeDir()
    this.food.refreshRandom(0, 290, 0, 290)
    this.gameStart()
  }

  //开启事件控制方向
  controlSnakeDir() {
    document.addEventListener('keyup', e => {
      this.resetGame(this.isGameOver, e)
      if (e.key === Direction.Up && this.snake.direction === Direction.Down) {
        return
      }
      if (
        e.key === Direction.Right &&
        this.snake.direction === Direction.Left
      ) {
        return
      }
      if (e.key === Direction.Down && this.snake.direction === Direction.Up) {
        return
      }
      if (
        e.key === Direction.Left &&
        this.snake.direction === Direction.Right
      ) {
        return
      }
      // 防止按下其他键&防抖
      let dir = ''
      switch (e.key) {
        case Direction.Up:
          dir = Direction.Up
          break
        case Direction.Right:
          dir = Direction.Right
          break
        case Direction.Down:
          dir = Direction.Down
          break
        case Direction.Left:
          dir = Direction.Left
          break
        default:
          dir = this.snake.direction
          break
      }
      // this.snake.direction = e.key
      if (timer !== null) {
        clearTimeout(timer)
      }
      timer = setTimeout(() => {
        this.snake.direction = dir
      }, 30)
    })
  }
  //游戏开始
  gameStart() {
    //展示食物和蛇
    //判断是否游戏结束
    //让蛇移动
    //食物碰撞检查功能
    if (this.isGameOver) return
    this.isGameOver = !this.snake.move()
    this.checkFoodCollision()
    setTimeout(() => {
      this.gameStart()
    }, this.snake.moveSpeed)
  }
  //食物检查函数
  checkFoodCollision() {
    let foodX = this.food.position.positionX
    let foodY = this.food.position.positionY
    let snakeX = this.snake.position.positionX
    let snakeY = this.snake.position.positionY
    if (foodX === snakeX && foodY === snakeY) {
      /**
       * 食物换位子
       * 通知蛇长大
       * 通知计分板增加
       * 通知蛇根据等级来加速
       */
      this.food.refreshRandom(0, 290, 0, 290)
      this.snake.groupUp()
      this.scorePanel.addScore()
      this.snake.moveFaster(this.scorePanel.Level)
      // console.log('吃到食物')
    }
  }
  /**
   *
   * @param isGameOver 传入游戏当前状态只有为真才会执行函数
   * @param event 键盘按键检查
   */
  resetGame(isGameOver: boolean, event: KeyboardEvent) {
    if (isGameOver && event.key === 'Enter') {
      this.snake = new Snake(150, 150)
      this.food = new Food()
      this.scorePanel = new ScorePanel()
      this.isGameOver = false
      this.controlSnakeDir()
      this.food.refreshRandom(0, 290, 0, 290)
      //显示蛇和食物
      this.snake.el.style.visibility = 'unset'
      this.food.el.style.visibility = 'unset'
      const title = document.getElementById('title')
      title!.style.display = 'none'

      this.gameStart()
    }
  }
}
